<?php


namespace app\api\controller\v1;


use app\lib\exception\ParamException;
use think\Controller;
use think\Db;
use think\Log;

class Token extends Controller
{
    /* 授权回调 */
    public function index()
    {
        $auth_code = $_GET['auth_code'] ?? '';

        $authorization_code = $_GET['authorization_code'] ?? '';

        $state = $_GET['state'] ?? '';

        if(!$state){
            return json(['code'=>400,'msg'=>'参数错误','errorCode'=>10000]);
            throw new ParamException(['msg'=>'参数错误','errorCode'=>10000]);
        }

        $states = explode('_',$state);
        if($states[0] == 'juliang'){
            if(!$auth_code){
                throw new ParamException(['msg'=>'参数错误','errorCode'=>10000]);
            }
            $this->getJuLiangAccessToken($auth_code,$states[1]);
        }

        if($states[0] == 'tengxun'){
            if(!$authorization_code){
                throw new ParamException(['msg'=>'参数错误','errorCode'=>10000]);
            }
            $this->getTengXunAccessToken($authorization_code,$states[1]);
        }
    }

    public function getTengXunAccessToken($auth_code,$admin_id)
    {
        $url = 'https://api.e.qq.com/oauth/token';

        $args = [
            'client_id' => config('acc.tx')['client_id'],
            'client_secret' => config('acc.tx')['client_secret'],
            'grant_type' => 'authorization_code',
            'redirect_uri' => 'http://ad.91duoxin.com',
            'authorization_code' => $auth_code
        ];

        foreach ($args as $key => $value) {
            $args[$key] = is_string($value) ? $value : json_encode($value);
        }

        $url = $url . "?" . http_build_query($args);
        $res = curl_get($url);
        Log::record($res, 'error');

//        $res = '{"code":0,"message":"","data":{"authorizer_info":{"account_uin":1286926829,"account_id":19043243,"account_name":"\u6cf0\u548c\u5353\u8d8a(\u5317\u4eac)\u91d1\u878d\u670d\u52a1\u5916\u5305\u6709\u9650\u516c\u53f8","login_name":1286926829,"scope_list":["user_actions","account_management","ads_insights","ads_management","audience_management"],"wechat_account_id":"","account_role_type":"ACCOUNT_ROLE_TYPE_ADVERTISER","account_type":"ACCOUNT_TYPE_ADVERTISER","role_type":"ROLE_TYPE_SELF_OPERATOR"},"access_token":"f12266145c3246bddcac3a540b1fa16f","refresh_token":"dbbb97570c2e8ac4b51f14547a142fee","access_token_expires_in":999999999,"refresh_token_expires_in":999999999}}';
//        $res = '{"code":0,"message":"","data":{"authorizer_info":{"account_uin":87954611,"account_id":21101324,"account_name":"\u91cd\u5e86\u4e24\u6c5f\u65b0\u533a\u901a\u878d\u5c0f\u989d\u8d37\u6b3e\u6709\u9650\u516c\u53f8","login_name":87954611,"scope_list":["user_actions","account_management","ads_insights","ads_management","audience_management"],"wechat_account_id":"","account_role_type":"ACCOUNT_ROLE_TYPE_ADVERTISER","account_type":"ACCOUNT_TYPE_ADVERTISER","role_type":"ROLE_TYPE_SELF_OPERATOR"},"access_token":"1f14d0e2f009422b9b3c8f1fe263073b","refresh_token":"3aa86e197ba057ad76c7d5a010100f5a","access_token_expires_in":999999999,"refresh_token_expires_in":999999999}}';
        $result = json_decode($res, true);
        if($result['code'] == 0){
            $account_id = $result['data']['authorizer_info']['account_id'];
            // 获取access_token同步账户信息
            $this->getTengXunAdvertiser($result['data']['access_token'], $account_id, $admin_id);

            $token = Db::name('access_token')->where(['admin_id'=>$admin_id,'channel_id'=>2,'account_id'=>$result['data']['authorizer_info']['account_id']])->find();
            if($token){
                Db::name('access_token')->where(['admin_id'=>$admin_id,'channel_id'=>2,'account_id'=>$result['data']['authorizer_info']['account_id']])->delete();
            }

            $params['admin_id'] = $admin_id;
            $params['channel_id'] = 2;
            $params['access_token'] = $result['data']['access_token'];
            $params['refresh_token'] = $result['data']['refresh_token'];
            $params['expires_time'] = time()+$result['data']['access_token_expires_in'];
            $params['account_id'] = $account_id;
            Db::name('access_token')->insert($params);

            $this->success('账号授权登录成功',"/manage/account/index");

        }else{
            throw new ParamException(['msg'=>$result['message'],'errorCode'=>30001]);
        }
    }

    public function getTengXunAdvertiser($access_token,$account_id,$admin_id)
    {
        $interface = 'advertiser/get';
        $url = 'https://api.e.qq.com/v1.1/' . $interface;

        $common_parameters = array (
            'access_token' => $access_token,
            'timestamp' => time(),
            'nonce' => md5(uniqid('', true))
        );

        $parameters = array (
            'account_id' => $account_id,
            'page' => 1,
            'fields'=>['corporation_name'],
            'page_size' => 100,
        );

        $parameters = array_merge($common_parameters, $parameters);

        foreach ($parameters as $key => $value) {
            if (!is_string($value)) {
                $parameters[$key] = json_encode($value);
            }
        }

        $request_url = $url . '?' . http_build_query($parameters);

        $res = curl_get($request_url);

        $result = json_decode($res, true);
        if($result['code'] == 0){
                $list = $result['data']['list'] ?? [];
                if(empty($list)){
                    throw new ParamException(['msg'=>'授权账户下没有广告账户','errorCode'=>30005]);
                }

                foreach ($list as $k=>$v){
                    $account = Db::name('account')->where(['adv_id' => $v['account_id']])->find();
                    if(!$account){
                        $params = [
                            'adv_id' => $v['account_id'],
                            'acc_name' => $v['corporation_name'],
                            'acc_desc' => $v['corporation_name'],
                            'macc_id' => $account_id,
                            'channel_id'=>2,
                            'admin_id'=>$admin_id,
                        ];

                        model('Account')->save($params);
                    }else{
                        if($account['admin_id'] != $admin_id){
                            throw new ParamException(['msg'=>'广告账户【'.$v['corporation_name'].'】已经被其他运营授权了','errorCode'=>30006]);
                        }
                    }
                }

                return true;
        }else{
            throw new ParamException(['msg'=>$result['message'],'errorCode'=>30003]);
        }
    }

    // 获取access_token
    public function getJuLiangAccessToken($auth_code,$admin_id)
    {

        $url = 'https://ad.oceanengine.com/open_api/oauth2/access_token/';
        $param = [
            'app_id'=>config('acc.jl')['app_id'],
            'secret'=>config('acc.jl')['secret'],
            'grant_type'=>'auth_code',
            'auth_code'=>$auth_code,
        ];
        $res = postJson($url, $param);

        //$res = '{"message": "OK", "code": 0, "data": {"advertiser_id": 1704707243040768, "advertiser_name": "\u4f01\u4e1a\u53f7", "access_token": "3681a7685de4f5a1286acba2694dd7a39a012124", "refresh_token_expires_in": 2591999, "advertiser_ids": [1704707243040768], "expires_in": 86399, "refresh_token": "7bec3cfdd835e888c002db987b3460bd427a9f75"}, "request_id": "202110172120340102060960444F43E999"}';
//        $res = '{"message": "OK", "code": 0, "data": {"advertiser_id": 1701440015522819, "advertiser_name": "XY\u534e\u7f8e\u6574\u5f62\u7f8e\u5bb9-59", "access_token": "6d57738adfe5ec9aac82a070e10f12f12cef751a", "refresh_token_expires_in": 2591999, "advertiser_ids": [1701440015522819], "expires_in": 86399, "refresh_token": "638643274841db89a66863e91b5b737784f13501"}, "request_id": "202110192125050101501581973302533D"}';

        $result = json_decode($res, true);
        if($result['code'] == 0){
            $advertiser_ids = $result['data']['advertiser_ids'];
            // 获取access_token同步账户信息
            foreach ($advertiser_ids as $v){
                $this->getJuLiangAdvertiser($result['data']['access_token'], $v, $admin_id);
            }

            $token = Db::name('access_token')->where(['admin_id'=>$admin_id,'channel_id'=>3,'advertiser_ids'=>json_encode($advertiser_ids)])->find();
            if($token){
                Db::name('access_token')->where(['admin_id'=>$admin_id,'channel_id'=>3,'advertiser_ids'=>json_encode($advertiser_ids)])->delete();
            }

            $params['admin_id'] = $admin_id;
            $params['channel_id'] = 3;
            $params['access_token'] = $result['data']['access_token'];
            $params['refresh_token'] = $result['data']['refresh_token'];
            $params['expires_time'] = time()+$result['data']['expires_in'];
            $params['advertiser_ids'] = json_encode($advertiser_ids);
            Db::name('access_token')->insert($params);

            $this->success('账号授权登录成功',"/manage/account/index");

        }else{
            throw new ParamException(['msg'=>$result['message'],'errorCode'=>20001]);
        }
    }

    //获取纵横组织下资产账户列表
    public function getJuLiangAdvertiser($access_token,$advertiser_id,$admin_id)
    {
        $url = 'https://ad.oceanengine.com/open_api/2/majordomo/advertiser/select/';

        $url = $url.'?advertiser_id='.$advertiser_id;

        $res = curl_get($url,$access_token);

        $result = json_decode($res, true);
        if($result['code'] == 0){
                $list = $result['data']['list'] ?? [];
                if(empty($list)){
                    throw new ParamException(['msg'=>'授权账户下没有广告账户','errorCode'=>20005]);
                }

                foreach ($list as $k=>$v){
                    $account = Db::name('account')->where(['adv_id' => $v['advertiser_id'],])->find();
                    if(!$account){
                        $params = [
                            'adv_id' => $v['advertiser_id'],
                            'acc_name' => $v['advertiser_name'],
                            'acc_desc' => $v['advertiser_name'],
                            'macc_id' => $advertiser_id,
                            'channel_id'=>3,
                            'admin_id'=>$admin_id,
                        ];

                        model('Account')->save($params);
                    }else{
                        if($account['admin_id'] != $admin_id){
                            throw new ParamException(['msg'=>'广告账户【'.$v['advertiser_name'].'】已经被其他运营授权了','errorCode'=>30006]);
                        }
                    }
                }

                return true;
        }else{
            throw new ParamException(['msg'=>$result['message'],'errorCode'=>20003]);
        }
    }

    // 获取已授权账户
    public function getJuLiangAccount($access_token)
    {
        $url = 'https://ad.oceanengine.com/open_api/oauth2/advertiser/get';

        $url = $url.'?app_id='.config('acc.jl')['app_id'].'&secret='.config('acc.jl')['secret'].'&access_token='.$access_token;

        $res = curl_get($url);
        $result = json_decode($res, true);
        if($result['code'] == 0){
                $list = $result['data']['list'] ?? [];
                if(empty($list)){
                    throw new ParamException(['msg'=>'未获取到授权账户','errorCode'=>20001]);
                }
        }else{
            throw new ParamException(['msg'=>'获取巨量已授权账户失败','errorCode'=>20001]);
        }
    }

    // 刷新token
    public function getJuLiangRefreshToken($refresh_token,$admin_id,$advertiser_ids)
    {
        $url = 'https://ad.oceanengine.com/open_api/oauth2/refresh_token/';
        $params = [
            'app_id'=>config('acc.jl')['app_id'],
            'secret'=>config('acc.jl')['secret'],
            'grant_type'=>'refresh_token',
            'refresh_token'=>$refresh_token,
        ];
        $res = postJson($url, $params);
        $result = json_decode($res, true);
        if($result['code'] == 0){
            try{
                $updates['access_token'] = $result['data']['access_token'];
                $updates['refresh_token'] = $result['data']['refresh_token'];
                $updates['expires_time'] = time()+$result['data']['expires_in'];
                Db::name('access_token')->where(['admin_id'=>$admin_id,'channel_id'=>3,'advertiser_ids'=>$advertiser_ids])->update($updates);

                return $result['data']['access_token'];
            }catch (\Exception $e){
                Log::error($e->getMessage());
                throw new ParamException(['msg'=>$e->getMessage(),'errorCode'=>20002]);
            }
        }else{
            throw new ParamException(['msg'=>'获取巨量access_token失败','errorCode'=>20001]);
        }
    }
}